<?php
namespace app\api\controller;
use think\Request;
use app\common\model\Travel as TravelModel;
use app\common\model\TravelMember;
use app\admin\model\Banks;
use app\api\controller\Webhook;
use data\Json;
use think\Cache;

class Pay extends Base
{
    protected  $api;
    protected  $appId;
    protected  $timestamp;
    protected  $appSign;
    protected  $times;

    public function _initialize()
    {
        if(version_compare(PHP_VERSION, '5.3.0','>')) {
            $this->api = new \beecloud\rest\api();
        }else{
            $this->api = new BCRESTApi();
        }
        $this->timestamp = time() * 1000;
        $this->api->registerApp(config('beecloud.app_id'),config('beecloud.app_secret'),
                                config('beecloud.master_secret'),config('beecloud.test_secret'));
        $this->api->setSandbox(true);

        $this->user_model = model('User');
        $this->token = request()->header('token');
        //$this->user = $this->user_model->getUserInfo($this->token);
        $this->user = $this->user_model->get('2');
    }

    public function test()
    {
        $pwd = '$2y$10$58hHL4Q1XMHv64v4SqtY6.VvuzYQnLCAsD6fvtl2705IA0EXCoxB6';//password_hash('123456', PASSWORD_DEFAULT);
        var_dump($pwd);
        var_dump(password_verify('123456', $pwd));exit;
    }

    // 实名认证
    public function auth(Request $request)
    {
        $user_model = input('type')==2?model('User'):model('Supplier');
       // $user = $user_model->getUserInfo($this->token);
        $user = $user_model->get('2');
        if(!$user)return Json::json_send(1);
        if($request->isPost())
        {
            try {
                $data = input();

                $vali = $this->validate($data,'User.auth');
                if($vali !== true) return Json::json_send($vali);

                $data['user_id'] = $user['id'];
                $authData = [
                    'name'  => $data['name'],
                    'id_no' => $data['id_no'],
                ];
                $result = \beecloud\rest\Auths::auth($authData);
                if ($result->result_code != 0) {
                    return Json::json_send(404,$result->errMsg);
                }
                $data['state'] = 1;
                $result = model('RealAuth')->save($data);
                if($result !== false)
                {
                    return Json::json_send(0);
                }
                return Json::json_send(404);
            }catch(Exception $e){
              echo $e->getMessage();
            }
        }
        $realAuth = model('RealAuth')->get(['type'=>input('type'),'user_id'=>$user['id']]);
        if($realAuth['card_abbr'])
        {
            $bank = Banks::where(['abbr'=>$realAuth['card_abbr']])->find();
            $realAuth['iconimage'] = $bank['iconimage'];
            $realAuth['backimage'] = $bank['backimage'];
            $realAuth['backname']  = $bank['name'];
        }
        return Json::json_send(0,'',$realAuth);
    }

    // 绑定银行卡
    public function bindbank(Request $request)
    {
        $user_model = input('type')==2?model('User'):model('Supplier');
        // $user = $user_model->getUserInfo($this->token);
        $user = $user_model->get('2');
        if(!$user)return Json::json_send(1);
        $realAuth = model('RealAuth')->get(['type'=>input('type'),'user_id'=>$user['id']]);
        if(!$realAuth)return Json::json_send(405);

        if($request->isPost())
        {
            try {
                $data = input();
                if($data['code']!== Cache::get($data['mobile'])) return Json::json_send(403);
                if($data['name'] !== $realAuth['name']) return Json::json_send(414);

                $authData = [
                    'name'    => $data['name'],
                    'id_no'   => $realAuth['id_no'],
                    'card_no' => $data['card_no'],
                    'mobile'  => $data['mobile'],
                ];
                $result = \beecloud\rest\Auths::auth($authData);
                if ($result->result_code != 0) {
                    // print_r($result);
                    return Json::json_send(404,$result->errMsg);
                }
                // print_r($result);
                $map = ['type'=>input('type'),'user_id'=>$user['id']];
                $data['card_abbr'] = getBankAbbr($data['card_no']);
                $result = model('RealAuth')->allowField(true)->save($data,$map);
                if($result !== false)
                {
                    return Json::json_send(0);
                }
                return Json::json_send(404);
            }catch(Exception $e){
              echo $e->getMessage();
            }
        }
        return Json::json_send(0,$realAuth);
    }

     // 设置交易密码
    public function transpwd(Request $request)
    {
        $user_model = input('type')==2?model('User'):model('Supplier');
        // $user = $user_model->getUserInfo($this->token);
        $user = $user_model->get('2');
        if(!$user)return Json::json_send(1);
        $realAuth = model('RealAuth')->get(['type'=>input('type'),'user_id'=>$user['id']]);
        if(!$realAuth) return Json::json_send(405);

        if($request->isPost())
        {
            try {
                $data = input();

                if(input('oldpwd'))
                {
                    if(!password_verify($data['oldpwd'], $realAuth['transpwd']))return Json::json_send(409);
                }

                if(input('id_no'))
                {
                   if($data['id_no'] !== $realAuth['id_no'])return Json::json_send(410);
                }
                if(empty($data['transpwd'])) return Json::json_send(407);
                if(empty($data['retranspwd'])) return Json::json_send(411);
                if($data['transpwd']!== $data['retranspwd']) return Json::json_send(408);
                $map = ['type'=>input('type'),'user_id'=>$user['id']];
                $data['transpwd'] = password_hash($data['transpwd'], PASSWORD_DEFAULT);
                $data['errortime'] = $data['errorcount'] = 0;
                $result = model('RealAuth')->allowField(true)->save($data,$map);

                if($result !== false)return Json::json_send(0);
                return Json::json_send(10);
            }catch(Exception $e){
              echo $e->getMessage();
            }
        }
        return Json::json_send(0,$realAuth);
    }

    // 充值
    public function recharge(Request $request)
    {
        $user_model = input('type')==2?model('User'):model('Supplier');
        // $user = $user_model->getUserInfo($this->token);
        $user = $user_model->get('2');
        if(!$user)return Json::json_send(1);
        if(input('channel') == 'UN_APP')
        {
            $realAuth = model('RealAuth')->get(['type'=>input('type'),'user_id'=>$user['id']]);
            if(!$realAuth['card_no']) return Json::json_send(412);
            if(!password_verify(input('transpwd'), $realAuth['transpwd']))return Json::json_send(413);
        }
        
        if($request->isPost())
        {
            $param = [
                'good_id'   => $user['id'],
                'total_fee' => input('fee',0),
                'title'     => '充值',
                'channel'   => input('channel','ALI_APP'),//"ALI_APP";
                'type'      => 7,//"充值";
            ];
            $this->redirect(url('pay/index', $param));
        }
    }

     // 提现
    public function withdrawals(Request $request)
    {
        $user_model = input('type')==2?model('User'):model('Supplier');
        // $user = $user_model->getUserInfo($this->token);
        $user = $user_model->get('2');
        if(!$user)return Json::json_send(1);
        $realAuth = model('RealAuth')->get(['type'=>input('type'),'user_id'=>$user['id']]);
        if(!$realAuth['card_no']) return Json::json_send(412);
        if(!password_verify(input('transpwd'), $realAuth['transpwd']))return Json::json_send(413);

        if($request->isPost())
        {
            $param = [
                'good_id'   => $this->user['id'],
                'total_fee' => input('fee',0),
                'title'     => '提现',
                'channel'   => input('channel','ALI_APP'),//"ALI_APP";
                'type'      => 8,//"提现";
            ];
            // 生成转账订单
            $order_id = action('pay/prepay',$param);
            $transData = [
                'order_id'  =>  $order_id,
                'name'      =>  $realAuth['name'],
                'id_no'     =>  $realAuth['id_no'],
                'bank_name' =>  Banks::where(['abbr'=>$realAuth['card_abbr']])->value('name'),
                'card_no'   =>  $realAuth['card_no'],
                'mobile'    =>  $realAuth['mobile'],
            ];
            // 申请转账
            $this->redirect(url('pay/transfer', $transData));
        }
    }

    public function blist()
    {
        $banks = \beecloud\rest\api::bc_transfer_banks(array('type' => 'P_DE'));
        var_dump($banks);exit;
        print_r($banks->bank_list);die;
    }


    // 支付  
    public function index()
    {
        $data = input();
        $data["timestamp"] =  $this->timestamp;
        $data["bill_no"] = date('Ymdh') . $data["timestamp"];
        $data['total_fee'] = $data['total_fee']*100;
        
        $result = model('Order')->allowField(true)->isUpdate(false)->save($data);
        if($result !== false)
        {
            if($data['channel'] == 'YE_APP')
            {
                $order = model('Order')->get(model('Order')->id);
                switch ($order['type']) {
                    case '1':
                        // 活动报名成功
                        return Webhook::travelMemberBusiness($order);
                        break;
                    case '2':
                        // 支付社群会费成功
                        return Webhook::communityBusiness($order);
                        break;
                    case '3':
                       // 海外游学支付尾款
                        return Webhook::tailBusiness($order);
                        break;
                    case '4':
                       // 发布活动支付定金
                        return Webhook::travelBusiness($order);
                        break;
                    default:
                        # code...
                        break;
                }
            }
            return Json::json_send(0,'',$data);
        }
    }

    //生成订单
    public function prepay()
    {
        $data = input();
        $data["timestamp"] =  $this->timestamp;
        $data["bill_no"] = date('Ymdh') . $data["timestamp"];

        $result = model('Order')->allowField(true)->isUpdate(false)->save($data);
        if($result !== false)
        {
            return model('Order')->id;
        }
    }
        

    // 退款功能
    public function refund()
    {
        $order_id = input('order_id',0);
        $order = model('Order')->get($order_id);

        $data["timestamp"] = time() * 1000;
        $data["bill_no"] = $order["bill_no"];

        //refund_no退款单号,为(预)退款使用的, 格式为:退款日期(8位) + 流水号(3~24 位)。
        //请自行确保在商户系统中唯一，且退款日期必须是发起退款的当天日期, 同一退款单号不可重复提交，否则会造成退款单重复。
        //流水号可以接受数字或英文字符，建议使用数字，但不可接受“000”
        $data["refund_no"] = date('Ymd',time()).time() * 1000;

        $data["refund_fee"] = (int)$order['total_fee'];

        $data["paid"] = 2;

        model('Order')->allowField(true)->save($data,['id' => $order['id']]); // 保存订单

        $data["channel"] = $this->getChannel($order["channel"]);

        try 
        {
            if(in_array($type, array('ALI_OFFLINE_QRCODE', 'ALI_SCAN', 'WX_SCAN', 'WX_NATIVE', 'BC_NATIVE', 'BC_WX_SCAN', 'BC_ALI_SCAN', 'BC_ALI_QRCODE'))){
                $result = $this->api->offline_refund($data);
            }else{
                $result = $this->api->refund($data);
            }
            if ($result->result_code != 0 || $result->result_msg != "OK") {
                print_r($result);
                exit();
            }
            //当channel为ALI_APP、ALI_WEB、ALI_QRCODE，并且不是预退款
            if((!isset($data["need_approval"]) || $data["need_approval"] === false) && $type == 'ALI'){
                header("Location:$result->url");
                exit();
            }
            echo (isset($_GET["need_approval"]) && $_GET["need_approval"] ? '预' : '')."退款成功, 退款表记录唯一标识ID: ".$result->id;

        } 
        catch (Exception $e) {
            echo $e->getMessage();
        }
    }


    // 企业转账
    public function transfer()
    {
        $order_id = input('order_id',0);
        $order = model('Order')->get($order_id);

        try {
        $data = array(
            'timestamp' => time() * 1000,
            'title' => '企业打款测试',   //订单标题
            'bill_no' => $order['bill_no'],    //订单编号
            'total_fee' => $order['total_fee'],//订单金额(int 类型) ,单位分
            'trade_source' => 'OUT_PC' ,//交易源, UTF8编码格式，目前只能填写OUT_PC
            'bank_fullname' => input('bank_name'), //银行全称
            'card_type' => "DE",//银行卡类型,区分借记卡和信用卡，DE代表借记卡，CR代表信用卡，其他值为非法
            'account_type' => "P", //帐户类型，P代表私户，C代表公户，其他值为非法
            'account_no' => input('card_no'),   //收款方的银行卡号
            'account_name' => input('name'), //收款方的姓名或者单位名
            //选填mobile
            'mobile' => input('mobile'), //银行绑定的手机号
        );
        $result = $this->api->bc_transfer($data);
        if ($result->result_code != 0) {
            print_r($result);
            exit();
        }
        echo ' 打款成功';
    } catch (Exception $e) {
        echo $e->getMessage();
    }
    }

    public function getChannel($type)
    {
       $channel = "";
       switch($type){
            case 'ALI_APP' :
                $title = "支付宝";
                $channel = "ALI";
                break;
            case 'WX_APP' :
                $title = "微信";
                $channel = "WX";
                break;
            case 'UN_APP' :
                $title = "银联";
                $channel = "UN";
                break;
            default :
                exit("No this type.");
                break;
        } 
        return $channel;
    }

    public function testBill()
    {
        if(!$this->user)return Json::json_send(1);
        $travel_id = input('travel_id',0);
        $type = TravelModel::where(['id'=>$travel_id])->value('type');
        $join = $type==1?'oversea':'activity';
        $travel = TravelModel::with($join)->where(['id'=>$travel_id])->find();
        $titles = [];
        foreach ($travel[$join] as $k => $v) {
           array_push($titles, $v['name']);
        } 

        $data['user_id'] = $this->user['id'];
        $data['good_id'] = $travel_id;
        $data["timestamp"] = $this->timestamp;
        $data["total_fee"] = $travel['memebr_price'];
        $data["bill_no"] = randCode() . $data["timestamp"];
        $data["title"] = implode('+',$titles);
        $data["channel"] = input('channel','ALI_APP');//"ALI_APP";

        $result = model('Order')->allowField(true)->isUpdate(false)->save($data);
        if($result !== false)
        {
            return Json::json_send(0,'',$data);
        }
      //  $result = $this->api->bill($data);
      //  var_dump($result);
        //$this->assertTrue(isset($result->result_code));
    }

    public function testBills()
    {
        $data["timestamp"] = $this->timestamp;
        $data["channel"] = "ALI";
        $data["limit"] = 10;
        $result = $this->api->bills($data);
        $this->assertGreaterThan(0, count($result->bills));
    }

    public function testBillCount()
    {
        $data["timestamp"] = $this->timestamp;
        $data["channel"] = "ALI";
        $result = $this->api->bills_count($data);
        $this->assertTrue(isset($result->count));
    }

    public function testRefund()
    {
        $data["timestamp"] = $this->timestamp;
        $data["bill_no"] = 'bcdemo1460634197000';
        $data["refund_no"] = '201604141460634675000';
        $data["refund_fee"] = 1;
        $data["channel"] = "ALI";
        $result = $this->api->refund($data);
        $this->assertNotEquals(0, $result->result_code);
    }

    public function testRefundStatus()
    {
        $data["timestamp"] = $this->timestamp;
        $data["channel"] = "WX";
        $data["refund_no"] = '20168888888888888888';
        $result = $this->api->refundStatus($data);
        $this->assertEquals('NO_SUCH_REFUND', $result->result_msg);
    }

    public function testRefunds()
    {
        $data["timestamp"] = $this->timestamp;
        $data["channel"] = "ALI";
        $data["limit"] = 10;
        $result = $this->api->refunds($data);
        $this->assertGreaterThan(0, count($result->refunds));
    }

    public function testRefundCount()
    {
        $data["timestamp"] = $this->timestamp;
        $data["channel"] = "ALI";
        $result = $this->api->refunds_count($data);
        $this->assertTrue(isset($result->count));
    }
}
